package cn.i7baozh.boot.learn.bean;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.config.ConstructorArgumentValues;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.beans.factory.support.GenericBeanDefinition;

/**
 * 注册方式2种：
 * 1. @Component注解
 * 2. 放到org.springframework.boot.autoconfigure.AutoConfiguration.imports中
 *
 * 在注册过程中如果需要读取配置文件的内容，可以实现ApplicationContextAware 获取到ApplicationContext 由此可以获取到 Environment 就能拿到配置了
 * @author zhangbaoqi532
 * @date 2025/3/18
 */
//@Component
public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor,
        BeanPostProcessor {

    //后执行
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {

        if (beanFactory.containsBean("myTestBean2")) {
            System.out.println("容器中已经存在myTestBean2");
            MyTestBean2 bean = beanFactory.getBean(MyTestBean2.class);
            bean.print();
        } else {
            System.out.println("容器中不存在myTestBean2");
            MyTestBean2 myTestBean2 = new MyTestBean2("postProcessBeanFactory传递");
            myTestBean2.init();
            beanFactory.registerSingleton("myTestBean2", myTestBean2);
        }
    }

    //先执行
    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
//        System.out.println("！！！！！！！！！！！所有加载的bean");
//        Arrays.stream(registry.getBeanDefinitionNames()).forEach(System.out::println);
        //移除一个bean
        registry.removeBeanDefinition("myTestBean");

        //新增一个bean
        GenericBeanDefinition beanDefinition = new GenericBeanDefinition();
        beanDefinition.setScope("singleton");
        beanDefinition.setBeanClass(MyTestBean2.class);
        //设置构造方法参数
        ConstructorArgumentValues constructorArgumentValues = new ConstructorArgumentValues();
        constructorArgumentValues.addIndexedArgumentValue(0,"postProcessBeanDefinitionRegistry传递");
        beanDefinition.setConstructorArgumentValues(constructorArgumentValues);
        //
        beanDefinition.setInitMethodName("init");
        beanDefinition.setDestroyMethodName("destroy");
        registry.registerBeanDefinition("myTestBean2",beanDefinition);
    }
}
